import idOptionEnum from "../enum/idOption.enum"
import {
  Conversion,
  ViewmodeConverter,
  SweepPlacementConverter,
  DirectionConverter,
  getPose,
  orientCameraUtils,
  AppPhaseConverter,
  ApplicationConverter,
  MediaConverter,
  ChunkTypeConverter,
  LinkTypeConverter,
  CommandModeConverter,
  CameraTransitionConverter,
  makeLabelDataUtil,
  makeModelDataUtil,
  SweepUtils,
  DependencyFetcher
} from "./utils"
import { LegacySweepIdMap, LegacyFloorIdMap, LegacyRoomIdMap, SweepIdMap, FloorIdMap, RoomIdMap } from "./legacy"
import app from "./app"
import camera from "./camera"
import floor from "./floor"
import label from "./label"
import mattertag from "./mattertag"
import measurements from "./measurements"
import mode from "./mode"
import model from "./model"
import pointer from "./pointer"
import renderer from "./renderer"
import room from "./room"
import scene from "./scene"
import sensor from "./sensor"
import settings from "./settings"
import stat from "./stat"
import sweep from "./sweep"
import tour from "./tour"
import custom from "./custom"
import Sdk from "../module/SdkModule"
import { exportOBJ, exportFUN, exportData } from "../sdk/sdk.module"
export type OBJ = typeof exportOBJ
export type Func = exportFUN
export type Data = exportData
/**
 * sdk初始化并暴露接口
 */
function setup(sdk: Sdk, exportThree, exportOBJ: OBJ, exportFunc: Func, exportData: Data, options: any = {}) {
  const { THREE } = exportThree
  const {
    appPhaseModule,
    applicationData,
    cameraData,
    canvasData,
    floorData,
    floorViewData,
    labelData,
    mattertagData,
    mattertagViewData,
    measurementModeData,
    meshData,
    modelData,
    raycasterData,
    roomData,
    settingsData,
    sweepData,
    sweepViewData,
    tourData,
    viewmodeData,
    commonControlsModule,
    floorCasterModule,
    mattertagDataModule,
    mattertagMeshModule,
    mattertagViewDataModule,
    modelDataModule,
    modelMeshModule,
    navigationModule,
    renderToTextureModule,
    sceneModule,
    sensorModule,
    settingsModule,
    tourControlsModule,
    webglRendererModule,
    zoomControlModule,
    sweepTextureLoader,
    extObjModule
  } = exportData
  options.idOption = options.idOption || idOptionEnum.LEGACY
  const conversionUtils = new Conversion(THREE)
  const ViewmodeConverterUtils = new ViewmodeConverter(exportOBJ.Viewmode)
  const rotateCameraUtils = async (t, o) => {
    const rotationSpeed = o.rotationSpeed
    let r = 0
    const a = Math.abs(o.xAngle),
      s = Math.abs(o.yAngle),
      i = Math.max(a, s)
    if (i >= Math.PI) {
      const e = i / Math.PI,
        t = Math.floor(e),
        o = a / e,
        n = s / e,
        d = a - o * t,
        c = s - n * t
      r = Math.acos(Math.cos(o) * Math.cos(n)) * t + Math.acos(Math.cos(d) * Math.cos(c))
    } else r = Math.acos(Math.cos(Math.abs(o.xAngle)) * Math.cos(Math.abs(o.yAngle)))
    if (r) {
      const a = new THREE.Vector2(-o.xAngle, o.yAngle)
      return a.multiplyScalar(rotationSpeed / r), t.startRotateTransition(r / rotationSpeed, a, !1)
    }
  }
  const SweepPlacementConverterUtils = new SweepPlacementConverter(exportOBJ.SweepAlignmentType, exportOBJ.SweepPlacementType)
  const LegacySweep = (async function () {
    const data = await sweepData
    return options.idOption === idOptionEnum.LEGACY ? new LegacySweepIdMap(data) : new SweepIdMap(data)
  })()
  const LegacyFloor = (async function () {
    const data = await floorData
    return options.idOption === idOptionEnum.LEGACY ? new LegacyFloorIdMap(data) : new FloorIdMap(data)
  })()
  const LegacyRoom = (async function () {
    const data = await roomData
    return options.idOption === idOptionEnum.LEGACY ? new LegacyRoomIdMap(data) : new RoomIdMap(data)
  })()
  const allFunc = Object.assign(Object.assign({}, exportFunc), {
    conversionUtils,
    directionConverter: new DirectionConverter(exportOBJ.Vectors),
    getPose: getPose(THREE, ViewmodeConverterUtils),
    rotateCamera: rotateCameraUtils,
    orientCamera: orientCameraUtils(THREE, exportOBJ.Viewmode, rotateCameraUtils),
    appPhaseConverter: new AppPhaseConverter(exportOBJ.AppPhase),
    applicationConverter: new ApplicationConverter(exportOBJ.Application),
    mediaConverter: new MediaConverter(exportOBJ.MattertagMediaType, exportOBJ.TagDescriptionChunkType),
    chunkTypeConverter: new ChunkTypeConverter(exportOBJ.TagDescriptionChunkType),
    linkTypeConverter: new LinkTypeConverter(exportOBJ.TagLinkType),
    sweepPlacementConverter: SweepPlacementConverterUtils,
    viewmodeConverter: ViewmodeConverterUtils,
    commandModeConverter: new CommandModeConverter(exportOBJ.CommandViewmode),
    cameraTransitionConverter: new CameraTransitionConverter(exportOBJ.CameraTransitionType),
    makeLabelData: makeLabelDataUtil(THREE, exportFunc.worldToScreenPosition),
    makeModelData: makeModelDataUtil(conversionUtils, SweepPlacementConverterUtils),
    sweepUtils: new SweepUtils(exportOBJ.SweepAlignmentType)
  })

  custom.Event(sdk)
  custom.highLightList(sdk, allFunc, new DependencyFetcher(tourData))
  custom.loadObjInfos(sdk, allFunc, new DependencyFetcher(extObjModule)) //0222 零时对象，

  app.Phase(sdk)
  app.Event(sdk)
  app.Application(sdk)
  app.getState(sdk, allFunc, new DependencyFetcher(appPhaseModule))
  app.getLoadTimes(sdk, allFunc, new DependencyFetcher(applicationData))
  app.state(sdk, exportOBJ, allFunc, new DependencyFetcher(applicationData))
  app.onEvent(sdk, exportOBJ, allFunc)

  camera.getPose(sdk, allFunc, new DependencyFetcher(cameraData, sweepData, viewmodeData, LegacySweep))
  camera.lookAtScreenCoords(sdk, THREE, allFunc, new DependencyFetcher(commonControlsModule, cameraData, viewmodeData))
  camera.moveInDirection(sdk, allFunc, new DependencyFetcher(navigationModule))
  camera.pan(sdk, THREE, allFunc, new DependencyFetcher(commonControlsModule, cameraData))
  camera.pose(sdk, THREE, allFunc, new DependencyFetcher(cameraData, sweepData, viewmodeData, LegacySweep))
  camera.rotate(sdk, THREE, allFunc, new DependencyFetcher(commonControlsModule, cameraData, viewmodeData))
  camera.setRotation(sdk, THREE, allFunc, new DependencyFetcher(commonControlsModule, cameraData, viewmodeData))
  camera.zoomTo(sdk, exportOBJ, allFunc, new DependencyFetcher(cameraData, viewmodeData, zoomControlModule))
  camera.zoomBy(sdk, exportOBJ, allFunc, new DependencyFetcher(cameraData, viewmodeData, zoomControlModule))
  camera.zoomReset(sdk, exportOBJ, allFunc, new DependencyFetcher(cameraData, viewmodeData, zoomControlModule))
  camera.zoom(sdk, exportOBJ, new DependencyFetcher(cameraData, viewmodeData))
  camera.takeScreenShot(sdk, THREE, exportOBJ, allFunc, new DependencyFetcher(canvasData, webglRendererModule, renderToTextureModule))
  camera.Event(sdk)
  camera.onEvent(sdk, allFunc, new DependencyFetcher(cameraData, sweepData, viewmodeData, LegacySweep))
  floor.current(sdk, exportOBJ, new DependencyFetcher(floorViewData, sweepData, cameraData, LegacyFloor))
  floor.data(sdk, new DependencyFetcher(floorData, LegacyFloor))
  floor.getData(sdk, allFunc, new DependencyFetcher(floorViewData))
  floor.moveTo(sdk, exportOBJ, allFunc, new DependencyFetcher(floorViewData))
  floor.showAll(sdk, exportOBJ, allFunc, new DependencyFetcher(floorViewData))
  floor.Event(sdk)
  floor.onEvent(sdk, exportOBJ, allFunc, new DependencyFetcher(floorData))

  label.Event(sdk)
  label.onEvent(sdk, exportOBJ, allFunc, new DependencyFetcher(cameraData, labelData, floorData, viewmodeData, LegacyFloor))
  label.getData(sdk, allFunc, new DependencyFetcher(cameraData, floorData, labelData, LegacyFloor))

  mattertag.Transition(sdk)
  mattertag.MediaType(sdk)
  mattertag.LinkType(sdk)
  mattertag.Event(sdk)
  mattertag.DescriptionChunkType(sdk)
  mattertag.getData(sdk, allFunc, new DependencyFetcher(mattertagData, floorData, LegacyFloor))
  mattertag.registerIcon(sdk, THREE, allFunc)
  mattertag.editIcon(sdk, THREE, allFunc, new DependencyFetcher(mattertagMeshModule, mattertagData))
  mattertag.resetIcon(sdk, allFunc, new DependencyFetcher(mattertagMeshModule, mattertagData))
  mattertag.editBillboard(sdk, exportOBJ, allFunc, new DependencyFetcher(mattertagData))
  mattertag.editColor(sdk, THREE, exportOBJ, allFunc, new DependencyFetcher(mattertagData))
  mattertag.editOpacity(sdk, new DependencyFetcher(mattertagData, mattertagMeshModule))
  mattertag.data(sdk, allFunc, new DependencyFetcher(mattertagData, floorData, LegacyFloor))
  mattertag.editPosition(sdk, THREE, exportOBJ, new DependencyFetcher(mattertagData, floorData, roomData, meshData))
  mattertag.navigateToTag(sdk, exportOBJ, allFunc)
  mattertag.preventAction(sdk, new DependencyFetcher(mattertagViewData))
  mattertag.remove(sdk, exportOBJ, allFunc)
  mattertag.closeBillboards(sdk, allFunc, new DependencyFetcher(mattertagViewDataModule))
  mattertag.onEvent(sdk, exportOBJ, allFunc, new DependencyFetcher(mattertagViewData))
  mattertag.injectHTML(
    sdk,
    function () {
      return "./sdk/mattertag/mattertag.postMessage.html"
    },
    new DependencyFetcher(mattertagData)
  )
  mattertag.add(sdk, THREE, exportOBJ, allFunc, new DependencyFetcher(floorData, roomData, meshData, mattertagDataModule))

  measurements.getData(sdk, allFunc, new DependencyFetcher(measurementModeData, floorData))
  measurements.mode(sdk, new DependencyFetcher(measurementModeData))
  measurements.toggleMode(sdk, exportOBJ, allFunc)
  measurements.data(sdk, exportOBJ, new DependencyFetcher(measurementModeData))

  mode.Event(sdk)
  mode.moveTo(sdk, THREE, exportOBJ, allFunc)
  mode.Mode(sdk, exportOBJ)
  mode.TransitionType(sdk)
  mode.onEvent(sdk, exportOBJ, allFunc, new DependencyFetcher(sweepData, viewmodeData))

  model.getData(sdk, allFunc, new DependencyFetcher(modelData, sweepData, floorData, LegacySweep))
  model.getDetails(sdk, exportOBJ, allFunc, new DependencyFetcher(modelData, settingsData))
  model.Event(sdk)
  model.onEvent(sdk, exportOBJ, allFunc, new DependencyFetcher(sweepData, floorData, LegacySweep))

  pointer.Colliders(sdk)
  pointer.intersection(sdk, THREE, exportOBJ, new DependencyFetcher(raycasterData, floorData, roomData, meshData))

  renderer.takeEquirectangular(
    sdk,
    THREE,
    exportOBJ,
    allFunc,
    new DependencyFetcher(webglRendererModule, renderToTextureModule, viewmodeData, sweepData, sweepTextureLoader)
  )
  renderer.getScreenPosition(sdk, exportOBJ, allFunc, new DependencyFetcher(webglRendererModule))
  renderer.getWorldPositionData(sdk, exportOBJ, allFunc, new DependencyFetcher(floorData, floorCasterModule))
  renderer.takeScreenShot(sdk, THREE, exportOBJ, allFunc, new DependencyFetcher(canvasData, webglRendererModule, renderToTextureModule))

  room.current(sdk, new DependencyFetcher(roomData, cameraData, sweepData, floorData, viewmodeData, meshData, LegacyRoom))
  room.data(sdk, new DependencyFetcher(roomData, floorData, LegacyRoom, meshData))

  scene.InteractionType(sdk)
  scene.Component(sdk)
  scene.register(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.createNode(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.query(sdk, allFunc, new DependencyFetcher(sceneModule, modelMeshModule))
  scene.configure(sdk, THREE, allFunc, new DependencyFetcher(webglRendererModule))
  scene.getImage(sdk, allFunc, new DependencyFetcher(modelDataModule))
  scene.deserialize(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.serialize(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.createNodes(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.registerComponents(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.createObjects(sdk, allFunc, new DependencyFetcher(sceneModule))
  // scene.SourceType(sdk, allFunc, new DependencyFetcher(sceneModule))
  scene.PathType(sdk)

  sensor.createSensor(sdk, new DependencyFetcher(sensorModule))
  sensor.createSource(sdk, THREE, exportOBJ)
  sensor.SensorType(sdk)
  sensor.SourceType(sdk)

  settings.get(sdk, exportOBJ, allFunc, new DependencyFetcher(settingsModule))
  settings.update(sdk, exportOBJ, allFunc, new DependencyFetcher(settingsModule))

  stat.Event(sdk)
  stat.onEvent(sdk, allFunc, new DependencyFetcher(settingsData))

  sweep.Transition(sdk)
  sweep.Alignment(sdk)
  sweep.Placement(sdk)
  sweep.data(sdk, allFunc, new DependencyFetcher(sweepData, floorData, LegacySweep, LegacyFloor))
  sweep.moveTo(sdk, exportOBJ, allFunc, new DependencyFetcher(sweepData, LegacySweep))
  sweep.current(sdk, exportOBJ, allFunc, new DependencyFetcher(sweepData, viewmodeData, floorData, LegacySweep, LegacyFloor))
  sweep.Event(sdk)
  sweep.onEvent(sdk, exportOBJ, allFunc, LegacySweep)
  sweep.enable(sdk, new DependencyFetcher(sweepData, sweepViewData, LegacySweep))
  sweep.disable(sdk, new DependencyFetcher(sweepData, sweepViewData, LegacySweep))

  tour.Event(sdk)
  tour.getData(sdk, exportOBJ, allFunc, new DependencyFetcher(tourControlsModule, tourData))
  tour.start(sdk, new DependencyFetcher(tourControlsModule, tourData))
  tour.stop(sdk, new DependencyFetcher(tourControlsModule, tourData))
  tour.step(sdk, new DependencyFetcher(tourControlsModule, tourData))
  tour.prev(sdk, new DependencyFetcher(tourControlsModule, tourData))
  tour.next(sdk, new DependencyFetcher(tourControlsModule, tourData))
  tour.onEvent(sdk, exportOBJ, allFunc)
}
export default setup
